﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace SheetLib.Matan
{
    public class ConnectedBlock
    {
        public Block Block;
        public ConnectionPlace ConnectionPlace;

        public ConnectedBlock(Block block, ConnectionPlace place) { Block = block; ConnectionPlace = place; }
    }

    public abstract class Block
    {
        protected List<ConnectedBlock> inputBlocks = new List<ConnectedBlock>();
        public List<ConnectedBlock> InputBlocks
        {
            get { return inputBlocks; }
        }

        protected int number = -1;
        public int Number 
        { 
            get { return number; } 
            set { number = value; } 
        }

        protected List<ConnectedBlock> outputBlocks = new List<ConnectedBlock>();
        public List<ConnectedBlock> OutputBlocks
        {
            get { return outputBlocks; }
            set { outputBlocks = value; }
        }

        protected int[] a = new int[3] { 1, 1, 1 };
        protected int[] b = new int[3] { 1, 1, 1 };

        public Block()
        {
            FillAB();            
        }

        protected abstract void FillAB();

        public static float[,] ComputeSMatrix(List<Block> blocks)
        {
            float[,] S = new float[blocks.Count, blocks.Count];
            for (int i = 0; i < blocks.Count; i++)
            {
                for (int j = 0; j < blocks[i].inputBlocks.Count; j++)
                {
                    S[i, blocks.IndexOf(blocks[i].inputBlocks[j].Block)] = 
                        (blocks[i].GetBlockType() == "+" && 
                            (bool)(blocks[i] as Blocks.SBlock).Parameters[((int)blocks[i].inputBlocks[j].ConnectionPlace).ToString()])
                         ? -1 : 1; // берутся параметры "1", "2" и "3", по-этому ConnectionPlace.ToString() (ConnectionPlace.Down <= ConnectionPlace <= ConnectionPlace.Up)
                }
            }

            return S;
        }

        public abstract string GetBlockType();
        public abstract int GetPower();

        protected Dictionary<string, object> parameters = new Dictionary<string, object>();
        public Dictionary<string, object> Parameters { get { return parameters; } }

        public override string ToString()
        {
            return GetBlockType() + " " + Number;
        }

        public static Block GetParticularBlock(string type)
        {
            Block block = null;

            Type[] blockTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
                t => (t.Namespace == "SheetLib.Matan.Blocks" && t.IsSubclassOf(typeof(Block)) 
                    && (Activator.CreateInstance(t) as Block).GetBlockType() == type)).ToArray();
            if (blockTypes.Length > 0)
            {
                block = (Block)Activator.CreateInstance(blockTypes[0]);
            }
            
            return block;
        }
    }
}
